package com.cw.jeeyt.service.impl.security;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.cw.jeeyt.common.Constants;
import com.cw.jeeyt.common.StringTools;
import com.cw.jeeyt.common.enums.EnumUserStatus;
import com.cw.jeeyt.common.utils.PasswordEncodeUtil;
import com.cw.jeeyt.common.utils.StringUtil;
import com.cw.jeeyt.common.utils.StringUtils;
import com.cw.jeeyt.core.util.SessionUtil;
import com.cw.jeeyt.dao.domain.security.SecurityOrgModel;
import com.cw.jeeyt.dao.domain.security.SecurityRoleModel;
import com.cw.jeeyt.dao.domain.security.SecurityUserModel;
import com.cw.jeeyt.dao.intf.security.SecurityOrgDao;
import com.cw.jeeyt.dao.intf.security.SecurityOrgUserDao;
import com.cw.jeeyt.dao.intf.security.SecurityRoleDao;
import com.cw.jeeyt.dao.intf.security.SecurityUserDao;
import com.cw.jeeyt.dao.intf.security.SecurityUserRoleDao;
import com.cw.jeeyt.dao.model.security.SecurityOrgDo;
import com.cw.jeeyt.dao.model.security.SecurityOrgUserDo;
import com.cw.jeeyt.dao.model.security.SecurityRoleDo;
import com.cw.jeeyt.dao.model.security.SecurityUserDo;
import com.cw.jeeyt.dao.model.security.SecurityUserRoleDo;
import com.cw.jeeyt.service.bo.security.SecurityOrgBo;
import com.cw.jeeyt.service.bo.security.SecurityUserBo;
import com.cw.jeeyt.service.bo.security.SecurityUserRoleBo;
import com.cw.jeeyt.service.bo.security.SecurityUserVo;
import com.cw.jeeyt.service.cache.CacheFacade;
import com.cw.jeeyt.service.converter.security.SecurityOrgConverter;
import com.cw.jeeyt.service.converter.security.SecurityUserConverter;
import com.cw.jeeyt.service.converter.security.SecurityUserRoleConverter;
import com.cw.jeeyt.service.impl.cache.SecurityOrgSupport;
import com.cw.jeeyt.service.intf.security.SecurityUserService;
import com.cw.jeeyt.service.utils.DataDicUtils;
import com.cw.lang.common.utils.CollectionUtil;
import com.cw.lang.common.utils.IdGenerator;
import com.cw.lang.common.utils.SequenceTool;
import com.cw.lang.mybatis.dto.PageInfo;

/**
 * 用户信息业务实现类
 *
 * @author chenw
 * @version 1.0.0
 */
@Service
public class SecurityUserServiceImpl implements SecurityUserService {

    private static final Logger logger = LoggerFactory.getLogger(SecurityUserServiceImpl.class);
    // 机构信息数据库操作接口
    @Autowired
    private SecurityOrgDao securityOrgDao;
    // 用户信息数据库操作接口
    @Autowired
    private SecurityUserDao securityUserDao;
    // 机构用户信息数据库操作接口
    @Autowired
    private SecurityOrgUserDao securityOrgUserDao;
    // 用户角色信息数据库操作接口
    @Autowired
    private SecurityUserRoleDao securityUserRoleDao;
    // 角色信息数据库操作接口
    @Autowired
    private SecurityRoleDao securityRoleDao;
    @Autowired
    private CacheFacade cacheFacade;
    @Autowired
    private SecurityOrgSupport securityOrgSupport;
    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 分页查询用户信息
     *
     * @param userBo
     * @param startNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<SecurityUserBo> queryByPage(SecurityUserBo userBo, Integer startNum, Integer pageSize)
    throws Exception {
        PageInfo<SecurityUserModel> pageInfo = securityUserDao.queryByPage(SecurityUserConverter.bo2Model(userBo),
            startNum, pageSize);
        List<SecurityUserBo> securityUserBos = SecurityUserConverter.modelList2BoList(pageInfo.getList());
        if (CollectionUtil.isNotEmpty(securityUserBos)) {
            Map<String, Object> dictMap = new HashMap<>();
            dictMap.put("status", "user_status");
            JSONArray jsonArray = DataDicUtils.convertDict(JSON.parseArray(JSON.toJSONString(securityUserBos)),
                dictMap);
            securityUserBos = JSON.parseArray(jsonArray.toJSONString(), SecurityUserBo.class);
        }
        return new PageInfo<>(pageInfo, securityUserBos);
    }

    /**
     * 根据主键查寻用户信息
     *
     * @param id
     * @return
     */
    @Override
    public SecurityUserBo getUserById(Long id) throws Exception {

        if (id == null) {
            logger.error("主键id为空");
            return null;
        }
        SecurityUserBo userBo = SecurityUserConverter.do2Bo(securityUserDao.getById(id));
        List<SecurityUserRoleDo> securityUserRoleList = securityUserRoleDao.queryUserRoleListByUserId(userBo.getId());
        Set<SecurityUserRoleBo> surList = new HashSet<>();
        if (securityUserRoleList != null && !securityUserRoleList.isEmpty()) {
            for (SecurityUserRoleDo securityUserRole : securityUserRoleList) {
                surList.add(SecurityUserRoleConverter.do2Bo(securityUserRole));
            }
        }
        userBo.setUserRoles(surList);
        return userBo;
    }

    /**
     * 根据用户名称查寻用户信息
     *
     * @param userName
     * @return
     */
    @Override
    public SecurityUserBo getUserByUserName(String userName) throws Exception {
        if (StringUtils.isEmpty(userName)) {
            logger.error("用户名称为空");
            return null;
        }
        return SecurityUserConverter.model2Bo(securityUserDao.findUserByName(userName));
    }

    /**
     * 新增用户信息
     *
     * @param userBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insert(SecurityUserBo userBo) throws Exception {

        if (userBo == null) {
            logger.error("用户信息为空");
            return null;
        }
        SecurityUserBo userVo = SessionUtil.getSessionUser();
        SecurityUserModel user = SecurityUserConverter.bo2Model(userBo);
        Long userId = IdGenerator.nextId();
        user.setId(userId);
        if (userVo != null) {
            user.setCreateBy(userVo.getId());// 创建人
            user.setUpdateBy(userVo.getId());// 修改人
        } else {
            user.setCreateBy(100L);// 创建人
            user.setUpdateBy(100L);// 修改人
        }
        user.setCreateDate(new Date());// 创建时间
        user.setUpdateDate(new Date());// 修改时间
        user.setPassword(PasswordEncodeUtil.encode(user.getPassword()));// 加密密码
        user.setUserState(true);
        user.setEnabled(true);
        user.setAccountNonExpired(true);
        user.setAccountNonLocked(true);
        user.setCredentialsNonExpired(true);
        user.setAccount(user.getUsername());
        securityUserDao.insert(user);
        // 保存用户角色信息
        String roleIds = userBo.getRoleIds();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdList = roleIds.split(",");
            for (String roleId : roleIdList) {
                SecurityUserRoleDo userRole = new SecurityUserRoleDo();
                userRole.setId(SequenceTool.nextId());
                userRole.setUserId(userId);
                userRole.setRoleId(Long.parseLong(roleId));
                securityUserRoleDao.insert(userRole);
            }
        }
        return 0;
    }

    /**
     * 更新用户信息
     *
     * @param userBo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SecurityUserBo userBo) throws Exception {

        if (userBo == null) {
            logger.error("用户信息为空");
            return;
        }
        SecurityUserModel user = SecurityUserConverter.bo2Model(userBo);
        user.setUpdateBy(SessionUtil.getSessionUserId());
        user.setUpdateDate(new Date());
        user.setEnabled(true);
        user.setAccountNonExpired(true);
        user.setAccountNonLocked(true);
        user.setCredentialsNonExpired(true);
        securityUserDao.update(user);
        // 保存用户角色信息
        String roleIds = userBo.getRoleIds();
        Long userId = userBo.getId();
        // 如果当前页面有角色信息，用户角色信息表没有，则新增
        // 如果当前页面没有角色信息，用户角色信息表有，则删除
        // 如果都存在，则不做操作
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdList = roleIds.split(",");
            for (String roleId : roleIdList) {
                SecurityUserRoleDo securityUserRole = securityUserRoleDao.checkSecurityUserRole(userId,
                    Long.parseLong(roleId));
                if (securityUserRole == null) {
                    SecurityUserRoleDo userRole = new SecurityUserRoleDo();
                    userRole.setId(SequenceTool.nextId());
                    userRole.setUserId(userId);
                    userRole.setRoleId(Long.parseLong(roleId));
                    securityUserRoleDao.insert(userRole);
                }
            }
        } else {
            List<SecurityUserRoleDo> securityUserRoleList = securityUserRoleDao.queryUserRoleListByUserId(userId);
            if (securityUserRoleList != null && !securityUserRoleList.isEmpty()) {
                for (SecurityUserRoleDo securityUserRole : securityUserRoleList) {
                    securityUserRoleDao.delete(securityUserRole);
                }
            }
        }
    }

    /**
     * 删除用户信息
     *
     * @param userBo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(SecurityUserBo userBo) throws Exception {

        if (userBo == null) {
            logger.error("用户信息为空");
            return;
        }
        securityUserDao.delete(SecurityUserConverter.bo2Model(userBo));
    }

    /**
     * 根据组织ID查询用户列表
     *
     * @param orgId 组织ID
     * @return 用户列表
     */
    @Override
    public List<SecurityUserVo> getUserListByOrgId(Long orgId) {
        List<SecurityUserDo> userList = securityUserDao.getUserListByOrgId(orgId);
        // 去重,当用户属于多个部门时,返回多条相同的用户记录
        List<SecurityUserDo> nList = new ArrayList<SecurityUserDo>();
        outer:
        for (SecurityUserDo userVo : userList) {
            for (SecurityUserDo user : nList) {
                if (user.getId()
                    .equals(userVo.getId())) {
                    continue outer;
                }
            }
            nList.add(userVo);
        }

        return SecurityUserConverter.doList2VoList(nList);
    }

    /**
     * 根据id查询用户
     *
     * @param userId 用户Id
     * @return 返回用户视图对象
     */
    public SecurityUserDo getUserVoById(Long userId, Long defaultOrgId) {
        SecurityUserModel user = securityUserDao.getUserVoById(userId);
        // 加入用户所属组织
        if (user == null) {
            return user;
        }
        List<SecurityOrgModel> securityOrgList = securityOrgDao.getSecurityOrgListByUserId(user.getId());
        // 获取用户当前公司以及下级组织
        // List<SecurityOrgDo> subOrgList = getSubSecurityOrgList(defaultOrgId);

        settingUserOrgUnitsRoles(user, defaultOrgId, securityOrgList);
        return user;
    }

    private SecurityOrgDo getSecurityOrgById(Long orgId) throws Exception {
        List<SecurityOrgBo> allOrgList = cacheFacade.getAllOrganizations();
        if (allOrgList != null) {
            for (SecurityOrgBo org : allOrgList) {
                if (org.getOrgId() != null && org.getOrgId()
                    .equals(orgId)) {
                    return SecurityOrgConverter.bo2Do(org);
                }
            }
        }

        return securityOrgDao.getById(orgId);
    }

    /**
     * 根据account获取用户
     *
     * @param account 用户账户
     * @return 用户视图对象
     */
    @Override
    public SecurityUserVo getUserByAccount(String account) {

        return SecurityUserConverter.do2Vo(securityUserDao.getUserByAccount(account));
    }

    @Override
    public SecurityUserVo getUserByUserId(String userId) {
        return SecurityUserConverter.do2Vo(securityUserDao.getUserByUserId(userId));
    }

    /**
     * 更新用户
     *
     * @param userBo
     */
    @Override
    public void modifyUser(SecurityUserBo userBo) {
        if (userBo == null) {
            logger.error("用户信息为空");
            return;
        }
        SecurityUserModel user = SecurityUserConverter.bo2Model(userBo);
        user.setUpdateBy(SessionUtil.getSessionUserId());// 更新人
        user.setUpdateDate(new Date());
        user.setEnabled(true);
        user.setAccountNonExpired(true);
        user.setAccountNonLocked(true);
        user.setCredentialsNonExpired(true);
        securityUserDao.update(user);
    }

    @Override
    public String resetPwd(Long id) {
        SecurityUserModel user = new SecurityUserModel();
        String resetPwd = "123456";
        user.setPassword(PasswordEncodeUtil.encode(resetPwd));
        user.setId(id);
        user.setUpdateDate(new Date());
        user.setUpdateBy(SessionUtil.getSessionUserId());
        securityUserDao.updateUserPassword(user);
        return resetPwd;
    }

    @Override
    public SecurityUserBo checkUserLogin(String account, String password) {
        SecurityUserBo userInfoBo = (SecurityUserBo) userDetailsService.loadUserByUsername(account);
        if (userInfoBo == null) {
            throw new BadCredentialsException("用户名不存在");
        }
        //这里判断密码正确与否
        if (!PasswordEncodeUtil.matches(password, userInfoBo.getPassword())) {
            throw new BadCredentialsException("密码不正确");
        }
        if (!userInfoBo.isEnabled()) {
            throw new BadCredentialsException("用户不可用");
        }
        if (!userInfoBo.isAccountNonExpired()) {
            throw new BadCredentialsException("用户密码已过期");
        }
        if (!userInfoBo.isAccountNonLocked()) {
            throw new BadCredentialsException("用户被锁");
        }
        if (!userInfoBo.isCredentialsNonExpired()) {
            throw new BadCredentialsException("用户凭证已过期");
        }
        return userInfoBo;
    }

    /**
     * * 新增用户
     *
     * @param user 用户视图对象
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    @Override
    public boolean addUser(SecurityUserVo user) throws Exception {
        // 处理默认用户密码为123456
        if (null == user.getPassword() || "".equals(user.getPassword())) {
            user.setPassword(PasswordEncodeUtil.encode("123456"));
        }
        user.setPassword(PasswordEncodeUtil.encode(user.getPassword()));
        user.setUpdateDate(new Date());
        securityUserDao.insert(SecurityUserConverter.vo2Model(user));

        String[] orgIdArr = user.getUserOrgIds()
            .split(";");
        persistUserAndOrgUnitRelation(user.getId(), orgIdArr);

        // 插入用户与角色的关联关系
        String[] roleIdArr = user.getUserRoleIds()
            .split(";");
        for (String roleId : roleIdArr) {
            if (StringUtils.isEmpty(roleId)) {
                continue;
            }
            if (securityRoleDao.getById(Long.parseLong(roleId)) == null) {
                if (logger.isWarnEnabled()) {
                    logger.warn("新增用户时，分配的角色：" + roleId + "已被删除！");
                }
                continue;
            }

            SecurityUserRoleDo userRole = new SecurityUserRoleDo();
            userRole.setUserId(user.getId());
            userRole.setRoleId(Long.parseLong(roleId));
            securityUserRoleDao.insert(userRole);
        }
        return true;
    }

    /**
     * * 新增用户 不再对密码进行加密 适用于已加过密的信息
     *
     * @param user 用户视图对象
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    @Override
    public boolean addUserByEncodePassword(SecurityUserVo user) throws Exception {
        // 处理默认用户密码为1
        if (null == user.getPassword() || "".equals(user.getPassword())) {
            user.setPassword("1");
        }
        user.setUpdateDate(new Date());
        securityUserDao.insert(SecurityUserConverter.vo2Model(user));

        String[] orgIdArr = user.getUserOrgIds()
            .split(";");
        persistUserAndOrgUnitRelation(user.getId(), orgIdArr);

        // 插入用户与角色的关联关系
        String[] roleIdArr = user.getUserRoleIds()
            .split(";");
        for (String roleId : roleIdArr) {
            if (StringUtils.isEmpty(roleId)) {
                continue;
            }
            if (securityRoleDao.getById(Long.parseLong(roleId)) == null) {
                if (logger.isWarnEnabled()) {
                    logger.warn("新增用户时，分配的角色：" + roleId + "已被删除！");
                }
                continue;
            }

            SecurityUserRoleDo userRole = new SecurityUserRoleDo();
            userRole.setUserId(user.getId());
            userRole.setRoleId(Long.parseLong(roleId));
            securityUserRoleDao.insert(userRole);
        }
        return true;
    }

    /**
     * 新增用户与机构关系
     *
     * @param userId
     * @param orgIdArr
     * @throws Exception
     */
    private void persistUserAndOrgUnitRelation(Long userId, String[] orgIdArr) throws Exception {
        List<SecurityOrgDo> list = new ArrayList<SecurityOrgDo>() {
            private static final long serialVersionUID = 1L;

            @Override
            public boolean add(SecurityOrgDo orgUnit) {
                if (orgUnit == null) {
                    return false;
                }
                return super.add(orgUnit);
            }
        };

        // 冗余的组织机构关系,例如A公司下有b部门，b部门下有子部门c，则b为冗余的关系,需剔除用户与b的关联关系
        for (String orgId : orgIdArr) {
            SecurityOrgDo theOrgUnit = getSecurityOrgById(Long.parseLong(orgId));
            list.add(theOrgUnit);
        }

        // 插入用户与组织的关联关系
        for (SecurityOrgDo orgUnit : list) {
            SecurityOrgUserDo userOrgUnit = new SecurityOrgUserDo();
            userOrgUnit.setUserId(userId);
            userOrgUnit.setOrgId(orgUnit.getOrgId());
            securityOrgUserDao.insert(userOrgUnit);
        }
    }

    /**
     * 更新用户，包含关联信息
     *
     * @param user 用户视图对象
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    @Override
    public boolean updateUser(SecurityUserVo user) throws Exception {

        user.setUpdateDate(new Date());
        Long defaultOrgId = user.getDefaultOrgId();
        user.setDefaultOrgId(securityOrgSupport.getOrgBelongedCompanyId(defaultOrgId));

        // 更新用户
        // 加密用户密码
        user.setPassword(PasswordEncodeUtil.encode(user.getPassword()));
        // 更新用户组织关联
        updateOrgUserRelations(user);
        // 更新用户角色关联
        updateUserRoleRelations(user);
        securityUserDao.update(SecurityUserConverter.vo2Model(user));
        return true;
    }

    /**
     * 更新用户组织关联
     *
     * @param user
     * @throws Exception
     */
    private void updateOrgUserRelations(SecurityUserVo user) throws Exception {
        // defaultOrgId为隶属组织，user.getUserOrgIds为所属组织，同时插入到用户组织关联表中
        String[] orgIdArr = user.getUserOrgIds()
            .split(";");

        if (orgIdArr == null || orgIdArr.length == 0) {
            return;
        }

        // 获取当前用户所在公司以及下级组织
        List<SecurityOrgModel> subOrgList = getSubSecurityOrgList(SessionUtil.getSessionUser()
            .getDefaultOrgId());

        // 当前登录用户有权限修改的那部分关联
        List<SecurityOrgUserDo> canUpdateOrg = new ArrayList<SecurityOrgUserDo>();
        // 获取用户原有的组织关联(旧的组织机构)
        List<SecurityOrgUserDo> oldUserOrgRelationList = securityOrgUserDao.getSecurityOrgUserByUserId(user.getId());
        // 遍历获取有权限修改的关联
        for (SecurityOrgUserDo userOrgRelation : oldUserOrgRelationList) {
            for (SecurityOrgDo securityOrg : subOrgList) {
                if (securityOrg.getOrgId()
                    .equals(userOrgRelation.getOrgId())) {
                    canUpdateOrg.add(userOrgRelation);
                }
            }
        }
        // 删除所有有权限更新的组织关联关系
        for (SecurityOrgUserDo userOrgRelation : canUpdateOrg) {
            securityOrgUserDao.deleteOrgUserByUserIdAndOrgId(userOrgRelation);
        }

        // 先删除用户与组织机构的关系
        securityOrgUserDao.deleteSecurityOrgUserByUserId(user.getId());
        // 插入新的组织关联关系
        persistUserAndOrgUnitRelation(user.getId(), orgIdArr);
    }

    /**
     * 更新用户角色关联
     *
     * @param user
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUserRoleRelations(SecurityUserVo user) throws Exception {
        // 新的角色ID
        String[] roleIdArr = user.getUserRoleIds()
            .split(";");
        // 获取用户原有的角色关联(旧的角色)
        List<SecurityUserRoleDo> oldUserRoleRelationList = securityUserRoleDao.queryUserRoleListByUserId(user.getId());

        // 获取当前用户所在公司以及下级组织
        List<SecurityOrgModel> subOrgList = getSubSecurityOrgList(SessionUtil.getSessionUser()
            .getDefaultOrgId());

        // 获取用户有权限修改的公司的所有角色
        List<SecurityRoleModel> roleList = new ArrayList<SecurityRoleModel>();
        for (SecurityOrgDo org : subOrgList) {
            if ("01".equals(org.getOrgType())) {
                roleList.addAll(securityRoleDao.getRolesByOrgId(org.getOrgId()));
            }
        }

        // 当前登录用户有权限修改的那部分关联
        List<SecurityUserRoleDo> canUpdateRole = new ArrayList<SecurityUserRoleDo>();
        // 遍历获取有权限修改的关联
        for (SecurityUserRoleDo userRoleRelation : oldUserRoleRelationList) {
            for (SecurityRoleModel role : roleList) {
                if (role.getId()
                    .equals(userRoleRelation.getRoleId())) {
                    canUpdateRole.add(userRoleRelation);
                }
            }
        }
        // 删除所有有权限更新的角色关联关系
        for (SecurityUserRoleDo userRoleRelation : canUpdateRole) {
            securityUserRoleDao.deleteUserRoleByUserIdAndRoleId(userRoleRelation);
        }

        // 删除其所有与角色的关联关系
        securityUserRoleDao.deleteUserRoleByUserId(user.getId());
        // 插入新的角色关联关系
        for (String roleId : roleIdArr) {
            if (StringUtils.isEmpty(roleId)) {
                continue;
            }
            if (securityRoleDao.getById(Long.parseLong(roleId)) != null) {
                SecurityUserRoleDo userRole = new SecurityUserRoleDo();
                userRole.setUserId(user.getId());
                userRole.setRoleId(Long.parseLong(roleId));
                securityUserRoleDao.insert(userRole);
            } else {
                if (logger.isWarnEnabled()) {
                    logger.warn("更新用户时，分配的角色：" + roleId + "已被删除！");
                }
            }
        }
        // 更新用户对应的角色缓存信息
        cacheFacade.discardUserRole(user.getId());
    }

    /**
     * 更新用户基础数据
     *
     * @param user 用户对象
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    @Override
    public boolean updateUser(SecurityUserBo user) throws Exception {
        int result = securityUserDao.update(SecurityUserConverter.bo2Model(user));
        return result > 0;
    }

    /**
     * 更新用户默认所属的组织
     *
     * @param user 用户对象
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    @Override
    public boolean updateUserDefaultOrgId(SecurityUserBo user) throws Exception {
        int result = securityUserDao.updateUserDefaultOrgId(SecurityUserConverter.bo2Model(user));
        return result > 0;
    }

    /**
     * 从给定组织中移除用户，如果用户不属于任何组织则删除此用户。
     *
     * @param userIds 用户Id数组
     * @param orgId 所需移除的组织
     * @return 成功返回true，失败返回false
     * @throws Exception
     */
    public boolean removeUserFromOrgUnit(String[] userIds, Long orgId) throws Exception {
        SecurityOrgDo securityOrg = getSecurityOrgById(orgId);
        // 如果是部门
        if (!"01".equals(securityOrg.getOrgType())) {
            securityOrg = securityOrgDao.getById(securityOrg.getOrgParentId());
        }
        for (String userId : userIds) {
            SecurityOrgUserDo userOrgUnit = new SecurityOrgUserDo();
            userOrgUnit.setOrgId(orgId);
            userOrgUnit.setUserId(Long.parseLong(userId));
            // 获取用户原有的组织关联(旧的组织机构)
            List<SecurityOrgUserDo> oldUserOrgRelationList = securityOrgUserDao.getSecurityOrgUserByUserId(
                Long.parseLong(userId));
            // 获取当前用户所在公司以及下级组织
            List<SecurityOrgModel> subOrgList = getSubSecurityOrgList(securityOrg.getOrgId());

            // 当前登录用户有权限修改的那部分关联
            List<SecurityOrgUserDo> canDeleteOrg = new ArrayList<SecurityOrgUserDo>();
            // 当前组织
            canDeleteOrg.add(userOrgUnit);
            // 遍历获取有权限修改的关联
            for (SecurityOrgUserDo userOrgRelation : oldUserOrgRelationList) {
                for (SecurityOrgDo org : subOrgList) {
                    if (org.getOrgId()
                        .equals(userOrgRelation.getOrgId())) {
                        canDeleteOrg.add(userOrgRelation);
                    }
                }
            }
            // 删除所有有权限更新的组织关联关系
            for (SecurityOrgUserDo userOrgRelation : canDeleteOrg) {
                securityOrgUserDao.deleteOrgUserByUserIdAndOrgId(userOrgRelation);
            }

            // 获取用户在该公司下的所有角色
            List<SecurityRoleModel> userRoleList = securityRoleDao.getRolesByUserId(Long.parseLong(userId));
            for (SecurityRoleDo role : userRoleList) {
                // 删除用户与该公司的角色的关联
                for (SecurityOrgDo org : subOrgList) {
                    if (org.getOrgId()
                        .equals(role.getId())) {
                        SecurityUserRoleDo userRole = new SecurityUserRoleDo();
                        userRole.setRoleId(role.getId());
                        userRole.setUserId(Long.parseLong(userId));
                        securityUserRoleDao.deleteUserRoleByUserIdAndRoleId(userRole);
                    }
                }
            }
        }
        // 最后把这些用户中，不属于任何组织的用户移除
        for (String id : userIds) {
            if (securityOrgUserDao.getSecurityOrgUserByUserId(Long.parseLong(id))
                .size() == 0) {
                SecurityUserModel user = securityUserDao.getById(Long.parseLong(id));
                if (user != null) {
                    // 备份用户信息到历史表
                    user.setUpdateDate(new Date());
                    securityUserDao.insert(user);
                    // 删除用户
                    securityUserDao.delete(user);
                }
            }
        }
        return true;
    }

    /**
     * 设置用户的所在组织机构和角色
     *
     * @param user 用户视图对象
     * @param defaultOrgId 登录用户当前所在的公司
     * @return
     */
    private void settingUserOrgUnitsRoles(SecurityUserModel user, Long defaultOrgId,
        List<SecurityOrgModel> orgUnitList) {
        // 用户所在的组织名称，多个以分号隔开
        String orgUnitIds = "";
        String orgUnitNames = "";
        for (SecurityOrgModel orgUnit : orgUnitList) {
            String orgName = orgUnit.getOrgName();

            // 如果是部门，在部门前添加公司简称
            if (!"01".equals(orgUnit.getOrgType())) {
                orgName = orgUnit.getParentOrgName() + "-" + orgName;
            }
            orgUnitNames = StringTools.uniteTwoStringBySemicolon(orgUnitNames, orgName, ";");
            orgUnitIds = StringTools.uniteTwoStringBySemicolon(orgUnitIds, orgUnit.getOrgId()
                .toString(), ";");
        }

        user.setUserOrgNames(orgUnitNames);
        user.setUserOrgIds(orgUnitIds);
        // 加入用户所属角色

        // cache the user's role list
        List<SecurityRoleDo> roleList = securityRoleDao.getRoleAndOrgNameListByUserId(user.getId());
        // 用户所拥有的角色名称，多个以分号隔开
        String roleNames = "";
        String roleIds = "";
        for (SecurityRoleDo role : roleList) {
            String roleName = role.getOrgName() + "-" + role.getName();
            roleNames = StringTools.uniteTwoStringBySemicolon(roleNames, roleName, ";");
            roleIds = StringTools.uniteTwoStringBySemicolon(roleIds, role.getId()
                .toString(), ";");
        }
        user.setUserRoleNames(roleNames);
        user.setUserRoleIds(roleIds);
    }

    /**
     * 根据角色Id获取用户列表
     *
     * @return 用户列表
     */
    @Override
    public List<SecurityUserBo> getUserListByRoleId(Long roleId) {
        return SecurityUserConverter.modelList2BoList(securityUserDao.getUserListByRoleId(roleId));
    }

    /**
     * 获取所有子公司及当前公司
     *
     * @param orgId
     * @return
     * @throws Exception
     */
    private List<SecurityOrgModel> getSubSecurityOrgList(Long orgId) throws Exception {
        SecurityOrgDo orgUnit = getSecurityOrgById(orgId);
        if (orgUnit == null) {
            return null;
        }

        return securityOrgDao.getSecurityOrgTreeByOrgLevelCode(orgUnit.getOrgLevelCode());
    }

    /**
     * 获取用户列表
     *
     * @param orgLevelCode
     * @return
     */
    @Override
    public List<SecurityUserVo> getDistinctUserListByOrgId(String orgLevelCode) {
        return SecurityUserConverter.doList2VoList(securityUserDao.getUserListByOrgId(Long.parseLong(orgLevelCode)));
    }

    /**
     * 更新用户状态
     *
     * @param account
     * @return
     * @throws Exception
     */
    @Override
    public void updateUserState(String account, String userState) throws Exception {
        securityUserDao.updateUserState(account, userState);
    }

    /**
     * 根据主键查询用户信息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public SecurityUserVo getSecurityUserDoById(Long userId, Long defaultOrgId) {
        return null;
    }

    /**
     * 根据默认组织机构ID、用户类型查找用户列表
     *
     * @param defaultOrgId 用户类型type
     * @return 用户列表
     */
    @Override
    public List<SecurityUserVo> getUserListByDefaultOrgIdAndType(Long defaultOrgId, String type) {
        return SecurityUserConverter.doList2VoList(
            securityUserDao.getUserListByDefaultOrgIdAndType(defaultOrgId, type));
    }

    /**
     * 用户注册
     */
    @Override
    public boolean registerUser(SecurityUserBo securityUser) throws Exception {
        boolean success = true;
        SecurityUserVo securityUserVo = this.getUserByAccount(securityUser.getAccount());
        if (securityUserVo != null && StringUtil.isNotEmpty(securityUserVo.getAccount())) {
            throw new Exception("账号已存在");
        }
        // 判断两次密码输入是否正确
        String password = securityUser.getPassword();
        String rePassword = securityUser.getRePassword();
        if (!password.equals(rePassword)) {
            throw new Exception("输入的两次密码不一致");
        }
        securityUser.setUsername(securityUser.getAccount());
        securityUser.setStatus(EnumUserStatus.VALID.getCode());
        // 分配权限
        SecurityRoleModel securityRole = securityRoleDao.getRoleByRoleName(Constants.ROLE_USER);
        securityUser.setRoleIds(securityRole.getId()
            .toString());
        // 保存注册信息
        this.insert(securityUser);
        return success;
    }

    /**
     * 修改密码
     */
    @Override
    public void updatePassword(SecurityUserBo userBo) throws Exception {
        SecurityUserModel securityUser = new SecurityUserModel();
        securityUser.setPassword(PasswordEncodeUtil.encode(userBo.getNewPassword()));
        securityUser.setId(userBo.getId());
        securityUser.setUpdateBy(SessionUtil.getSessionUserId());
        securityUser.setUpdateDate(new Date());
        securityUserDao.updateUserPassword(securityUser);
    }

    @Override
    public List<SecurityUserBo> queryListByCondition(SecurityUserBo securityUser) {

        if (securityUser == null) {
            logger.error("用户信息为空");
            return null;
        }

        return SecurityUserConverter.modelList2BoList(
            securityUserDao.queryListByCondition(SecurityUserConverter.bo2Model(securityUser)));
    }

}
